package com.affectu.opus.action;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.faces.model.SelectItem;
import javax.imageio.ImageIO;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

import com.affectu.category.Category;
import com.affectu.category.CategoryAction;
import com.affectu.dao.DAOBase;
import com.affectu.opus.Opus;

/**
 * Sep 28, 2008
 * 
 * @author daniel nathan
 */
@Name("opusIndexAction")
@Scope(ScopeType.SESSION)
public class Index extends DAOBase {

	private String opusImageUrl;

	private long categoryId = -1;// avoid null exception

	private long subCategoryId = -1;

	@SuppressWarnings("unchecked")
	public List<Opus> getOwnOpuses() {
		List<Opus> opuses = new ArrayList<Opus>();
		try {
			opuses = em
					.createSQLQuery(
							"select o.* from Opus o where o.ownerId=:ownerId  order by o.id desc")
					.addEntity("o", Opus.class).setParameter("ownerId",
							this.getCurrentUser().getId()).list();
		} catch (Exception ex) {
			this.logException(ex);
		}
		return opuses;
	}

	public long getSubCategoryId() {
		return subCategoryId;
	}

	public void setSubCategoryId(long subCategoryId) {
		this.subCategoryId = subCategoryId;
	}

	public long getCategoryId() {
		return categoryId;
	}

	public void setCategoryId(long categoryId) {
		this.categoryId = categoryId;
	}

	public List<SelectItem> getFirstCategoryItems() {
		List<SelectItem> items = new ArrayList<SelectItem>();
		try {
			CategoryAction ca = new CategoryAction();
			List<Category> cats = ca.getCategoriesByLevel(1);
			for (Category cat : cats) {
				SelectItem item = new SelectItem(cat.getId(), cat.getName());
				items.add(item);
			}

		} catch (Exception ex) {
			this.logException(ex);
		}
		return items;
	}

	public List<SelectItem> getSubCategoryItems() {
		List<SelectItem> items = new ArrayList<SelectItem>();
		try {
			List<Category> cats = this.getCategoryById(this.getCategoryId())
					.getChildren();
			for (Category cat : cats) {
				SelectItem item = new SelectItem(cat.getId(), cat.getName());
				items.add(item);
			}

		} catch (Exception ex) {
			this.logException(ex);
		}
		return items;
	}

	public Category getCategoryById(long catId) {
		Category category = new Category();
		try {
			Object obj = em.get(Category.class, catId);
			if (obj instanceof Category) {
				category = (Category) obj;
			}
		} catch (Exception ex) {
			this.logException(ex);
		}
		return category;
	}

	public String saveOpus(Opus opus) {
		try {
			opus.setImageUrl(opusImageUrl);
			opus.setCategory(this.getCategoryById(this.getSubCategoryId()));
			opus.setOwner(this.getCurrentUser());
			em.save(opus);
			this.getSessionScope().remove("opusIndexAction");
		} catch (Exception ex) {
			this.logException(ex);
		}
		return "/opus/index.xhtml";
	}

	public String deleteOpus(Opus opus) {
		try {
			String filepath = this.getRealPath("/") + "upload/opus/";
			File file = new File(filepath, opus.getImageUrl());
			File small_file = new File(filepath, "small_" + opus.getImageUrl());
			file.delete();
			small_file.delete();
			em.delete(opus);
		} catch (Exception ex) {
			this.logException(ex);
		}
		return "";
	}

	public void uploadListener(UploadEvent event) {
		try {
			UploadItem item = event.getUploadItem();
			String fileName = item.getFileName();
			fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);

			Random rand = new Random();
			opusImageUrl = this.getCurrentUser().getId() + "_"
					+ rand.nextInt(9999) + "_" + fileName;// 防止同名文件产生
			String filepath = this.getRealPath("/") + "upload/opus/";
			File file = new File(filepath, opusImageUrl);
			FileInputStream fis = new FileInputStream(item.getFile());
			FileOutputStream out = new FileOutputStream(file);
			int bytes = 0;
			byte[] bteFile = new byte[1024];
			while ((bytes = fis.read(bteFile)) != -1) {
				out.write(bteFile, 0, bytes);
			}
			out.flush();
			out.close();

			File fo = new File(filepath, "small_" + this.opusImageUrl); // 将要转换出的小图文件
			int nw = 120;
			AffineTransform transform = new AffineTransform();
			BufferedImage bis = ImageIO.read(file);
			int w = bis.getWidth();
			int h = bis.getHeight();
			int nh = (nw * h) / w;
			double sx = (double) nw / w;
			double sy = (double) nh / h;
			transform.setToScale(sx, sy);
			System.out.println(w + " " + h);
			AffineTransformOp ato = new AffineTransformOp(transform, null);
			BufferedImage bid = new BufferedImage(nw, nh,
					BufferedImage.TYPE_3BYTE_BGR);
			ato.filter(bis, bid);
			ImageIO.write(bid, "jpeg", fo); //			

			FacesMessages.instance().add("文件上传成功！" + filepath + opusImageUrl);
		} catch (Exception ex) {
			FacesMessages.instance().add("文件上传失败！");
			this.logException(ex);
		}
	}

}
